package com.tianlang.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.kit.PropKit;
import com.megvii.cloud.http.CommonOperate;
import com.megvii.cloud.http.Response;
import com.tianlang.model.dto.FaceV3;

/**
 * 人脸检测服务
 * 
 */
public class FaceUtils {

	/**
	 * 调用Face++ 实现人脸检测
	 * 
	 * @param imageUrl 待检测图片的访问地址
	 * @return List<Face> 人脸列表
	 */
	private static List<FaceV3> faceDetect(String imageUrl) {
		List<FaceV3> faceList = new ArrayList<FaceV3>();
		try {
			String key = PropKit.get("faceAppKey");
			String secret = PropKit.get("faceAppSecret");
			String attributes = PropKit.get("attributes", null);
			CommonOperate commonOperate = new CommonOperate(key, secret, false);
			Response response = commonOperate.detectUrl(imageUrl, 0, attributes);
			if (response.getStatus() == 200) {
				String res = new String(response.getContent());
				JSONObject json = JSON.parseObject(res);
				JSONArray faces = json.getJSONArray("faces");
				// 遍历检测到的人脸
				for (int i = 0; i < faces.size(); i++) {
					// face
					JSONObject faceObject = (JSONObject) faces.get(i);
					String faceToken = faceObject.getString("face_token");
					// 人脸矩形框的位置
					JSONObject faceRectangle = faceObject.getJSONObject("face_rectangle");
					int top = faceRectangle.getIntValue("top");
					int left = faceRectangle.getIntValue("left");
					// attribute
					JSONObject attributesObject = faceObject.getJSONObject("attributes");
					// 性别
					String gender = attributesObject.getJSONObject("gender").getString("value");
					int age = attributesObject.getJSONObject("age").getIntValue("value");
					String ethnicity = attributesObject.getJSONObject("ethnicity").getString("value");
					FaceV3 face = new FaceV3();
					face.set("faceToken", faceToken);
					face.set("top", top);
					face.set("left", left);
					face.set("gender", genderConvert(gender));
					face.set("age", age);
					face.set("ethnicity", raceConvert(ethnicity));
					faceList.add(face);
				}
				// 将检测出的Face按从左至右的顺序排序
				Collections.sort(faceList);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return faceList;
	}

	/**
	 * 性别转换（英文->中文）
	 * 
	 * @param gender
	 * @return
	 */
	private static String genderConvert(String gender) {
		String result = "男性";
		if ("Female".equals(gender)) {
			result = "女性";
		}
		return result;
	}

	/**
	 * 人种转换（英文->中文）
	 * 
	 * @param race
	 * @return
	 */
	private static String raceConvert(String race) {
		String result = "黄色";
		if ("Asian".equals(race))
			result = "黄色";
		else if ("White".equals(race))
			result = "白色";
		else if ("Black".equals(race))
			result = "黑色";
		return result;
	}

	/**
	 * 根据人脸识别结果组装消息
	 * 
	 * @param faceList 人脸列表
	 * @return
	 */
	private static String makeMessage(List<FaceV3> faceList) {
		StringBuffer buffer = new StringBuffer();
		// 检测到1张脸
		if (1 == faceList.size()) {
			buffer.append("共检测到 ").append(faceList.size()).append(" 张人脸").append("\n");
			for (FaceV3 face : faceList) {
				buffer.append(face.getStr("ethnicity")).append("人种,");
				buffer.append(face.getStr("gender")).append(",");
				buffer.append(face.getInt("age")).append("岁左右").append("\n");
			}
		} else if (faceList.size() > 1 && faceList.size() <= 10) {
			// 检测到2-10张脸
			buffer.append("共检测到 ").append(faceList.size()).append(" 张人脸，按脸部中心位置从左至右依次为：").append("\n");
			for (FaceV3 face : faceList) {
				buffer.append(face.getStr("ethnicity")).append("人种,");
				buffer.append(face.getStr("gender")).append(",");
				buffer.append(face.getInt("age")).append("岁左右").append("\n");
			}
		} else if (faceList.size() > 10) {
			// 检测到10张脸以上
			buffer.append("共检测到 ").append(faceList.size()).append(" 张人脸").append("\n");
			// 统计各人种、性别的人数
			int asiaMale = 0;
			int asiaFemale = 0;
			int whiteMale = 0;
			int whiteFemale = 0;
			int blackMale = 0;
			int blackFemale = 0;
			for (FaceV3 face : faceList) {
				String ethnicity = face.getStr("ethnicity");
				String gender = face.getStr("gender");
				if ("黄色".equals(ethnicity)) {
					if ("男性".equals(gender)) {
						asiaMale++;
					} else {
						asiaFemale++;
					}
				} else if ("白色".equals(ethnicity)) {
					if ("男性".equals(gender)) {
						whiteMale++;
					} else {
						whiteFemale++;
					}
				} else if ("黑色".equals(ethnicity)) {
					if ("男性".equals(gender)) {
						blackMale++;
					} else {
						blackFemale++;
					}
				}
			}
			if (0 != asiaMale || 0 != asiaFemale) {
				buffer.append("黄色人种：").append(asiaMale).append("男").append(asiaFemale).append("女").append("\n");
			}
			if (0 != whiteMale || 0 != whiteFemale) {
				buffer.append("白色人种：").append(whiteMale).append("男").append(whiteFemale).append("女").append("\n");
			}
			if (0 != blackMale || 0 != blackFemale) {
				buffer.append("黑色人种：").append(blackMale).append("男").append(blackFemale).append("女").append("\n");
			}
		}
		// 移除末尾空格
		if (buffer.length() > 0) {
			buffer = new StringBuffer(buffer.substring(0, buffer.lastIndexOf("\n")));
		}
		return buffer.toString();
	}

	/**
	 * 提供给外部调用的人脸检测方法
	 * 
	 * @param picUrl 待检测图片的访问地址
	 * @return String
	 */
	public static String detect(String picUrl) {
		// 默认回复信息
		String result = "未识别到人脸，请换一张清晰的照片再试！" + WeiXinUtils.emoji(0x1F4F7);
		List<FaceV3> faceList = faceDetect(picUrl);
		if (faceList.size() > 0) {
			try {
				result = makeMessage(faceList);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return result;
	}

	public static void main(String[] args) throws Exception {
		String imageUrl = "http://pic1.hebei.com.cn/003/005/869/00300586905_449eedbb.jpg";
		// System.out.println(detect(picUrl));
		String key = "-iGvC7IQnPPx-ZA6GLCy0_DKFcmaV5Tn";
		String secret = "zeInNA8iDpEtMJcEDAjkucKklW4cmUgN";
		CommonOperate commonOperate = new CommonOperate(key, secret, false);
		Response response = commonOperate.detectUrl(imageUrl, 0, "gender,age,smiling,glass,headpose,facequality,blur");
		if (response.getStatus() == 200) {
			String res = new String(response.getContent());
			JSONObject json = JSON.parseObject(res);
			String faceToken = json.getJSONArray("faces").getJSONObject(0).getString("face_token");
			System.out.println(faceToken);
		}

	}
}
